<template>
	<el-card class="box-card mb-1" id="search">
		<el-form :model="forms" :rules="rules" ref="ruleForm" :inline="true" size="mini">
			<slot v-for="item in config.form" :key="item.key" :name="item.key" :row="item">
				<el-form-item :label="item.label" :prop="item.key" v-if="!item.hide">
					<template v-if="item.type == 'select'">
						<el-select
							v-if="item.remote === true"
							v-model="forms[item.key]"
							:placeholder="item.placeholder || '请选择'"
							:loading="selectOptions[item.key].remoteLoading"
							:remote-method="remoteMethod(item.key)"
							filterable
							remote
						>
							<el-option
								v-for="opt in selectOptions[item.key].list"
								:key="opt.value"
								:label="opt.label"
								:value="opt.value"
							></el-option>
						</el-select>
						<el-select v-else v-model="forms[item.key]" :placeholder="item.placeholder || '请选择'">
							<el-option
								v-for="opt in item.options"
								:key="opt.value"
								:label="opt.label"
								:value="opt.value"
							></el-option>
						</el-select>
					</template>
					<template v-else-if="item.commentsName === 'datePicker'">
						<el-date-picker
							v-model="forms[item.key]"
							:type="item.type"
							:placeholder="item.placeholder || '请选择'"
							:format="item.format || 'YYYY-MM-DD'"
							:value-format="item.format || 'YYYY-MM-DD'"
							:start-placeholder="item.startPlaceholder || '请选择开始日期'"
							:end-placeholder="item.endPlaceholder || '请选择结束日期'"
							:disabledDate="item.disabledDate || ''"
							:range-separator="item.disabledDate || '至'"
							:shortcuts="item.shortcuts || []"
						></el-date-picker>
					</template>
					<template v-else-if="item.commentsName === 'timeSelect'">
						<el-time-select
							v-model="forms[item.key]"
							:start="item.start"
							:step="item.step"
							:end="item.end"
							:placeholder="item.placeholder || '请选择'"
						></el-time-select>
					</template>
					<template v-else>
						<el-input
							@input="inputLimiting(item.key, item.handlerLimiting)"
							v-model.trim="forms[item.key]"
							:maxlength="item.maxlength"
							:type="item.type"
							:placeholder="item.placeholder || '请选择'"
						></el-input>
					</template>
				</el-form-item>
			</slot>
			<el-form-item>
				<el-button icon="el-icon-search" type="primary" @click="handlerSearch()" :loading="loading">
					{{ loading ? '搜索中' : '搜索' }}
				</el-button>
				<el-button :disabled="loading" icon="el-icon-refresh" @click="queryResetForm()">
					重置
				</el-button>
			</el-form-item>
		</el-form>
	</el-card>
</template>
<script lang="ts">
	import { defineComponent, reactive, toRefs, onMounted, getCurrentInstance, watch } from 'vue';
	import { CommonSearchProps } from './interface';

	export default defineComponent({
		name: 'commonsearch',
		props: {
			modelValue: {
				type: String,
				require: true,
			},
			config: {
				type: Object,
				require: true,
			},
		},
		setup(ctx, context) {
			let ruleForm = null;

			let data: CommonSearchProps = reactive({
				loading: false,
				forms: {},
				rules: {},
				selectOptions: {},
			});

			onMounted(() => {
				ruleForm = getCurrentInstance().proxy.$refs['ruleForm'];
			});

			ctx.config.form.forEach(item => {
				// 默认值
				data.forms[item.key] = item.defaultValue;
				// 组装验证器
				data.rules[item.key] = item.rules;
				// 远程搜索列表映射
				if (item.remote) {
					data.selectOptions[item.key] = {
						remoteLoading: false,
						list: [],
					};
				}
			});

			//update:modelValue：通过该指令 能进行v-model的双向数据绑定
			context.emit('update:modelValue', data.forms);

			// 监听form数据发生改变
			watch(data.forms, () => {
				context.emit('update:modelValue', data.forms);
			});

			// 输入限制
			let inputLimiting = (key, callback) => {
				if (callback) {
					data.forms[key] = callback(data.forms[key]);
				}
			};
			// 搜索
			let handlerSearch = () => {
				ruleForm.validate(async valid => {
					if (valid) {
						data.loading = true;
						let params = {};
						Object.keys(data.forms).forEach(key => {
							if (
								data.forms[key] !== '' &&
								data.forms[key] !== 'null' &&
								data.forms[key] !== 'undefined' &&
								data.forms[key] !== null &&
								data.forms[key] !== undefined
							) {
								params[key] = data.forms[key];
							}
						});
						await ctx.config.handlerSearch(params);
						data.loading = false;
					}
				});
			};

			// 远程搜索
			let remoteMethod = (key: string) => {
				let res = ctx.config.form.find(item => item.key === key);
				return async query => {
					if (query !== '') {
						data.selectOptions[key].remoteLoading = true;
						data.selectOptions[key].list = await res.getOptions();
						data.selectOptions[key].remoteLoading = false;
					} else {
						data.selectOptions[key].list = [];
						data.selectOptions[key].remoteLoading = false;
					}
				};
			};

			// 重置
			const queryResetForm = async () => {
				Object.keys(data.forms).forEach(key => {
					data.forms[key] = '';
				});
				ruleForm.resetFields();
				await ctx.config.handlerSearch();
				data.loading = false;
			};

			return {
				handlerSearch,
				queryResetForm,
				remoteMethod,
				inputLimiting,
				...toRefs(data),
			};
		},
	});
</script>
